package marionito.usecasesimpl;

import java.util.ArrayList;
import java.util.List;

import javax.ejb.EJB;
import javax.ejb.Lock;
import javax.ejb.LockType;
import javax.ejb.Singleton;

import marionito.dao.CaseDao;
import marionito.dao.JetonDao;
import marionito.dao.JoueurDao;
import marionito.dao.JoueurPartieDao;
import marionito.dao.PartieDao;
import marionito.domaine.Case;
import marionito.domaine.Jeton;
import marionito.domaine.Joueur;
import marionito.domaine.JoueurPartie;
import marionito.domaine.Partie;
import marionito.domaine.Partie.Etat;
import marionito.usecases.GestionParties;

@Singleton
public class GestionPartiesImpl implements GestionParties {

	@EJB
	private JoueurDao joueurDao;

	@EJB
	private PartieDao partieDao;

	@EJB
	private JetonDao jetonDao;

	@EJB
	private CaseDao caseDao;

	@EJB
	private JoueurPartieDao joueurPartieDao;

	public static List<Jeton> jetons;

	@Override
	public void creerJetons() {
		if (jetons == null) {
			jetons = new ArrayList<Jeton>(12);
			for (int i = 1; i <= 12; i++) {
				Jeton j = new Jeton(i);
				jetonDao.enregistrer(j);
				jetons.add(j);
			}
		}
	}

	@Override
	public Partie creerPartie(String nomPartie) {
		if (partieDao.rechercherPartie(nomPartie) != null)
			return null;

		Partie partie = new Partie(nomPartie);
		partie = this.partieDao.enregistrer(partie);
		return partie;

	}

	@Override
	public Partie rejoindrePartie(String nomPartie, String j) {
		Partie partie = this.partieDao.rechercherPartie(nomPartie);
		if (partie == null)
			return null;

		Joueur joueur = joueurDao.rechercher(j);
		if (joueur == null)
			return null;

		JoueurPartie joueurPartie = new JoueurPartie(partie, joueur);
		joueurPartie = joueurPartieDao.enregistrer(joueurPartie);

		partie = partieDao.mettreAJour(partie);
		partie = partieDao.chargerJoueurs(partie);
		partie = partieDao.chargerJetons(partie);
		return partie;
	}

	@Override
	public Partie chargerTout(Partie partie) {
		partie = this.partieDao.chargerJoueurs(partie);
		partie = this.partieDao.chargerJetons(partie);
		return partie;
	}

	@Override
	public Partie chargerJoueurs(Partie partie) {
		partie = this.partieDao.chargerJoueurs(partie);
		return partie;
	}

	@Override
	@Lock(LockType.READ)
	public List<Partie> listerParties() {
		return this.partieDao.lister();
	}

	@Override
	@Lock(LockType.READ)
	public List<Partie> listerPartiesPasCommencee() {
		return this.partieDao.listerPartiesEtat(Etat.PAS_COMMENCEE);
	}

	@Override
	@Lock(LockType.READ)
	public List<Partie> listerPartiesCommencee() {
		return this.partieDao.listerPartiesEtat(Etat.COMMENCEE);
	}

	@Override
	@Lock(LockType.READ)
	public List<Partie> listerPartiesTerminee() {
		return this.partieDao.listerPartiesEtat(Etat.TERMINEE);
	}

	@Override
	public int lancerDe(String nomPartie) {
		Partie partie = partieDao.rechercherPartie(nomPartie);
		if (partie == null)
			return -1;
		return partie.lancerDe();
	}

	@Override
	@Lock(LockType.READ)
	public List<String> listerJoueurs(String nomPartie) {
		Partie partie = partieDao.rechercherPartie(nomPartie);
		if (partie == null)
			return null;
		List<JoueurPartie> listJoueurs = partie.getJoueursPartie();
		List<String> pseudos = new ArrayList<String>();
		for (JoueurPartie jp : listJoueurs)
			pseudos.add(jp.getJoueur().getLogin());
		return pseudos;
	}

	@Override
	@Lock(LockType.READ)
	public boolean contientJoueur(String nomPartie, Joueur joueur) {
		List<String> list = listerJoueurs(nomPartie);
		if (list.contains(joueur.getLogin())) {
			return true;
		}
		return false;
	}

	@Override
	@Lock(LockType.READ)
	public List<Jeton> commencerPartie(String nomPartie) {
		Partie partie = partieDao.rechercherPartie(nomPartie);
		if (partie == null)
			return null;
		return partie.commencerPartie();
	}

	@Override
	public void annulerPartie(String nomPartie) {
		Partie partie = partieDao.rechercherPartie(nomPartie);
		partie.getJoueursPartie();
		for (JoueurPartie jp : partie.getJoueursPartie()) {
			joueurPartieDao.supprimer(jp.getId());
		}

		partieDao.supprimer(partie.getId());
	}

	@Override
	public List<Case> listeCases(Joueur joueur, String nomPartie) {
		Partie partie = partieDao.rechercherPartie(nomPartie);
		if (partie == null)
			return null;
		return caseDao.lister(joueur, partie);
	}

	@Override
	public Jeton jetonSuivant(String nomPartie) {
		Partie partie = partieDao.rechercherPartie(nomPartie);
		if (partie == null)
			return null;
		partie = partieDao.chargerJetons(partie);
		return partie.jetonSuivant();
	}

	@Override
	public Case ajouterJeton(Joueur joueur, String nomPartie, Jeton jeton,
			String numCasePlace) {
		Partie partie = partieDao.rechercherPartie(nomPartie);
		if (partie == null)
			return null;

		Case caseRempl = caseDao.recherche(joueur, partie, Integer.parseInt(numCasePlace));
		caseRempl.setJeton(jeton);
		caseRempl = caseDao.mettreAJour(caseRempl);

		return caseRempl;
	}

	@Override
	public Partie recherchePartie(String nomPartie) {
		return this.partieDao.rechercherPartie(nomPartie);
	}

	@Override
	public Case remplacerJeton(Joueur joueur, String nomPartie,
			String valeurJetonPlace, String numCasePlace) {
		Partie partie = partieDao.rechercherPartie(nomPartie);
		if (partie == null)
			return null;

		Case ancienneCase = caseDao.rechercheCase(joueur, partie,
				Integer.parseInt(valeurJetonPlace));
		Jeton jeton = jetonDao.rechercherJeton(valeurJetonPlace);
		ancienneCase.setJeton(null);
		ancienneCase = caseDao.mettreAJour(ancienneCase);

		return ajouterJeton(joueur, nomPartie, jeton, numCasePlace);
	}

	@Override
	public List<Joueur> listerVainqueurs(String nomPartie) {
		Partie partie = partieDao.rechercherPartie(nomPartie);
		if (partie == null)
			return null;

		return partie.vainqueurs();
	}

	@Override
	public List<JoueurPartie> listeJoueursScores(String nomPartie) {
		Partie partie = partieDao.rechercherPartie(nomPartie);
		if (partie == null)
			return null;
		
		return partie.scoresTriesPartie();
	}

}
